<template>
  <Category :disabled='!isShowList'/>
  <el-card
    shadow="always"
    :body-style="{ padding: '20px' }"
    :style="{ marginTop: '30px' }"
  >
    <template #header v-if="isShowList">
      <el-button
        type="primary"
        size="default"
        @click="addAttr"
        :icon="Plus"
        :disabled="!category3Id"
        >新增属性</el-button
      >
    </template>
    <!-- card body -->
    <el-table border stripe :data="attrList" v-if="isShowList">
      <el-table-column label="序号" type="index" width="80" />
      <el-table-column
        label="属性名称"
        width="150"
        prop="attrName"
      ></el-table-column>
      <el-table-column label="属性值名称列表" prop="attrValueList">
        <template v-slot="{ row }">
          <el-tag
            type="danger"
            size="default"
            effect="dark"
            v-for="item in row.attrValueList"
            >{{ item.valueName }}</el-tag
          >
        </template>
      </el-table-column>
      <el-table-column label="操作" width="150">
        <template v-slot="{ row }">
          <el-button
            type="warning"
            size="default"
            @click="editAttr(row)"
            :icon="Edit"
          ></el-button>
          <el-popconfirm
            title="你确定要删除这个属性吗?"
            @confirm="deleteAttr(row)"
          >
            <template #reference>
              <el-button
                type="danger"
                size="default"
                :icon="Delete"
              ></el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div v-else>
      <el-form label-width="80px" :inline="true" style="margin-top: 30px">
        <el-form-item label="属性名">
          <el-input
            placeholder="请输入属性名"
            v-model="newAttrData.attrName"
          ></el-input>
        </el-form-item>
      </el-form>
      <div>
        <el-button
          type="primary"
          @click="addAttrValue"
          :disabled="!newAttrData.attrName"
          >添加属性值</el-button
        >
        <el-button type="default" @click="cancle">取消</el-button>
      </div>
      <el-table
        border
        stripe
        :style="{ marginTop: '30px' }"
        :data="newAttrData.attrValueList"
      >
        <el-table-column type="index" width="50" label="序号" />
        <el-table-column label="属性值名称" prop="valueName">
          <template v-slot="{ row, $index }">
            <el-input
              ref="editEle"
              v-model="row.valueName"
              placeholder="请输入新增的属性值名称"
              size="default"
              v-if="row.isEdit"
              @blur="changeToLook(row, $index)"
              @focus="saveOldValue(row)"
            ></el-input>
            <span
              v-else
              @click="changeToEdit(row)"
              :style="{ display: 'inline-block', width: '70%' }"
              >{{ row.valueName }}</span
            >
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ $index }">
            <el-popconfirm
              title="你确定要删除这个属性吗?"
              @confirm="deleteAttrValue($index)"
            >
              <template #reference>
                <el-button
                  type="danger"
                  size="default"
                  icon="ele-Delete"
                ></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div style="margin-top: 30px">
        <el-button
          type="primary"
          @click="saveAttr"
          :disabled="newAttrData.attrValueList.length <= 0 ||!newAttrData.attrName" 
          >保存</el-button
        >
        <el-button type="default" @click="cancle">取消</el-button>
      </div>
    </div>
  </el-card>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from "element-plus";

export default defineComponent({
  name: "Attr",
});
</script>

<script setup lang="ts">
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import { watch, ref, nextTick } from "vue";
import useAttrStore from "@/stores/attr";
import { storeToRefs } from "pinia";
import type {
  attrListType,
  attrListItemType,
  attrValueListType,
} from "@/api/attr";
import {
  requestAttrList,
  requestUpdateOrAddAttr,
  requestDeleteAttr,
} from "@/api/attr";
import { cloneDeep } from "lodash";
const attrStore = useAttrStore();
const { category1Id, category2Id, category3Id } = storeToRefs(attrStore);

//1. 获取属性列表的逻辑
// 存放三级分类得到的属性列表
const attrList = ref<attrListType>([]);

//封装一个获取属性列表的请求函数
const getArrList = async () => {
  const result = await requestAttrList(
    category1Id.value as number,
    category2Id.value as number,
    category3Id.value as number
  );
  attrList.value = result;
};
//监听第三级分类的改变,然后请求属性列表
watch(
  category3Id,
  (newValue) => {
    //如果3级列表项变为了null,则把属性列表的数据清空
    if (!newValue) {
      attrList.value = [];
      return;
    }
    getArrList();
  },
  { immediate: true }
);

//2.添加平台属性逻辑
//定义一个新增平台属性的一个初始数据,将来新增点击保存的时候,把这个值提交
const newAttrData = ref<attrListItemType>({
  attrName: "",
  categoryId: category3Id.value as number,
  categoryLevel: 3,
  attrValueList: [],
});
//数据保存平台属性页是否展示,可以切换到新增或修改页
const isShowList = ref(true);

// 新增平台属性事件函数
const addAttr = () => {
  isShowList.value = false;
  //每次新增的时候,清空上一次可能残留的数据(重新给newAttrData赋一个初始值)
  newAttrData.value = {
    attrName: "",
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: [],
  };
};

//取消新增或者修改的功能及视图
const cancle = () => {
  //先切换到属性列表页
  isShowList.value = true;
};

// 给新增的属性 添加属性值的事件回调函数
const addAttrValue = () => {
  // 创建一个属性值的数据
  const newAttrValue = ref({
    valueName: "", //当前新增属性值的内容(目前为空占位,等视图渲染后,在input中数据双向绑定输入)
    attrId: newAttrData.value.id, //当前属性值所在的属性的id(就算是新增,属性没有id,我们也要关联,将来后端添加id的时候,我就有值了)
    isEdit: true, //我们给新增的属性值数据中添加一个逻辑 isEdit代表当前模式是否是编辑模式(新增的数据肯定是编辑模式)
  });
  // 把新增的属性值数据 添加到新属性的 属性值列表的数组中
  newAttrData.value.attrValueList.push(newAttrValue.value);
  nextTick(() => {
    // console.log(editEle.value);

    editEle.value.focus();
  });
};

// 在属性列表中修改某个属性的事件方法
const editAttr = (row: attrListItemType) => {
  //先切换到新增或者添加属性页
  isShowList.value = false;
  //在回调数据的时候,我们遍历row中的所有的属性值,给每一个属性值对象添加一个isEdit值为false(因为回填的数据默认是查看模式)
  const cloneRow = cloneDeep(row);
  cloneRow.attrValueList.forEach((item) => {
    item.isEdit = false;
  });
  //回填数据,因为视图和初始新增数据的newAttrData进行深度绑定,所以回填的时候,直接把被修改的数据赋值给newAttrData即可
  newAttrData.value = cloneRow;
};

//创建一个数据用来保存编辑模式的input元素
const editEle = ref();
//切换查看模式到编辑模式 给span绑定的点击事件回调函数
const changeToEdit = (row: attrValueListType) => {
  //row是当前属性值所在的数据,把当前的数据中的isEdit变为true
  row.isEdit = true;
  //让当前的表单自动获取焦点(操作真实DOM的时候,看情况要放在nextTick中,等DOM加载完成才能执行)
  nextTick(() => {
    // console.log(111);

    editEle.value.focus();
  });
};

let oldAttrValueName = "";
//给编辑模式绑定获取焦点事件,保存旧值
const saveOldValue = (row: attrValueListType) => {
  //先把当前的旧值保存起来
  oldAttrValueName = row.valueName;
  console.log(oldAttrValueName);
};

//切换到查看模式的事件回调函数
const changeToLook = (row: attrValueListType, $index: number) => {
  //row是当前属性值所在的数据,把当前的数据中的isEdit变为false
  row.isEdit = false;
  // 判断输入的是否为空
  if (!row.valueName.trim()) {
    //如果输入为空,并且旧值也为空,那么说明当前是新增属性值,并且用户没有填,直接删除
    if (!oldAttrValueName) {
      newAttrData.value.attrValueList.splice($index, 1);
    } else {
      //如果有旧值,则直接把旧值还给用户,并且把旧值清空
      row.valueName = oldAttrValueName;
    }
  }

  //判断用户输入的是否有重复选项,如果有,则恢复
  let isRepeat = newAttrData.value.attrValueList.some((item) => {
    //如果自己比较自己的时候,我们跳过(不挑过的话,永远isRepeat为true)
    if (item === row) {
      return;
    }
    return item.valueName === row.valueName;
  });

  //判断在数据列表中除了row自身以外,还有没有谁的valueName值和row的相等,如果有,则恢复旧值
  if (isRepeat) {
    if (oldAttrValueName) {
      row.valueName = oldAttrValueName;
    } else {
      newAttrData.value.attrValueList.splice($index, 1);
    }
  }

  //统一在失去焦点事件结束的时候 清空旧值
  oldAttrValueName = "";
};
//确认删除某条属性值的回调函数
const deleteAttrValue = ($index: number) => {
  newAttrData.value.attrValueList.splice($index, 1);
  // console.log(111);
};

//确认保存修改或者新增的属性值列表
const saveAttr = async () => {
  //newAttrData就是我们发送请求的参数
  //1.在保存值的时候把isEdit属性删除调
  newAttrData.value.attrValueList.forEach((item) => {
    delete item.isEdit;
  });

  // 2.判断当前的属性值列表是否为空,如果为空就不提交了
  if (newAttrData.value.attrValueList.length <= 0) {
    ElMessage.error("属性值列表不能为空");
    return;
  }

  // 发送请求
  try {
    await requestUpdateOrAddAttr(newAttrData.value);
    ElMessage.success("新增或者修改成功");
    //返回属性列表视图
    isShowList.value = true;
    //重新发送请求
    getArrList();
  } catch (e) {
    ElMessage.error("新增或者修改失败");
  }
};

//删除某条属性的回调函数
const deleteAttr = async (row: attrListItemType) => {
  //发送删除请求
  try {
    await requestDeleteAttr(row.id as number);
    ElMessage.success("删除属性成功");
    //重新发送请求
    getArrList();
  } catch (e) {
    ElMessage.error("删除属性失败");
  }
};
</script>
